//
//  AVGData.h
//  Chart
//
//  Created by CaoJun on 13-6-3.
//
//

#ifndef __Chart__AVGData__
#define __Chart__AVGData__

#include "Quotation.h"
#include "Metal.h"
#include "Rectangle.h"
#include "IndexConfigInterface.h"
#include "UserGraphInterface.h"
#include "YTXTime.h"
#include "json.h"

// std::pair
#include <utility>
#include <vector>
#include <tuple>
#include <list>
#include <string>

namespace ytx {

    struct EconomicCalendarData {
        YTXTime ecTime;
        std::string ecTitle;
        std::string ecName;
        std::string ecCountry;
        std::string ecFormerValue;
        std::string ecPredictedValue;
        std::string ecPublishedValue;
        int dataId;
        std::string json;
    };
    
    typedef std::tuple<double, double, bool> LimitPositionInfo;

    class AVGData : public Quotation, public IndexConfigInterface, public UserGraphInterface, public Observable<AVGData>
    {
    private:
        double closeSum;
        int exitDataCount;
        bool isPush();

        double getCloseSum();
        void setCloseSum(double closeSum);

        void pushData(std::vector<std::vector<double> > & avgData, std::vector<std::string> & date, std::vector<KLineItem> & kLineItems);

        void setData(std::vector<std::vector<double> > & avgData, std::vector<std::string> & date, std::vector<KLineItem> & kLineItems, double preclose, YTXTime tradedate);
        
        KLineItem getLastData();

        bool quotedPriceFlag;// update(YES);push(NO)

//        int checkShowCountStep(int step);

//        int checkStartIndexStep(int step);

        KLineItem quotedPrice;

        std::vector<double> warningLineData;
        std::list<double> buyPoints;
        
        std::list<LimitPositionInfo> limitPositionInfos;
        
    protected:
        virtual AVGData * getObservable();
        void processdata(std::vector<std::vector<double> > & avgData, std::vector<std::string> & date, std::vector<KLineItem> & kLineItems, double preclose, YTXTime tradedate, std::string updateTime);
        void removeLastData();
        bool inSameMinute(std::string t1, std::string t2);

        void updateLastData(std::string pricetime, double open, double close, double high, double low, double volume, double value, double totalHold, double avg, double totalVolume, double totalValue);
        
        void updateLastDataTotalVolumeValue(double totalVolume, double totalValue);

        std::vector<std::pair<YTXTime, YTXTime> > restTime;

        YTXTime tradedate;

        YTXTime nextTradedate;

        YTXTime nextTradedateStartTime;

        YTXTime nextTradedateEndTime;

        YTXTime openTime;

        YTXTime closeTime;
        
        virtual void responsePrevData(YTXJson::Value datas, YTXJson::Value info);
        
        virtual void behaviorFactory(std::string behaviorName);

        void calculateEmpty();
        //同步日期
        YTXTime updateDate(YTXTimeDuration time);
        
        std::vector<EconomicCalendarData> economicCalendarDataList;
        
        bool economicCalendarDataFlag;
        
        int biddingTime;
        
    public:
        int addDay;
        
        std::string updateTime;
        int baseDrawCount;
        
        TimeString calTimeString;
        
        AVGData(std::string id,std::string currentDate, std::string marketType, int toFix, std::string name, std::string nickName, YTXTime openTime, YTXTime closeTime, int dataSum, bool hasVolume, TimeString timeString, Rect row, Rect column, std::vector<std::pair<YTXTime, YTXTime> > restTime);
        AVGData(AVGData *);
        virtual ~AVGData();
        
        virtual std::vector<std::pair<std::string, std::string> > getTopSideText(const std::vector<std::vector<double> > & data, int index) const;
        virtual std::vector<std::pair<double, std::string> > getLeftSideText(int startIndex, int endIndex, const Rectangle & rect, const Style & style) const;
        virtual const std::vector<std::string> & getBottomSideText(SizeType::SizeType widthType) const;
        virtual std::pair<double, double> getDataMinMax(int startIndex, int endIndex) const;
        virtual std::pair<double, double> getAdjustedDataMinMax(int startIndex, int endIndex, const Rectangle & rect) const;
        
        void clearAllData();
        
        virtual void cleanData();

        void calculate();

        virtual std::string getCrosshairYData(int index);

        virtual double getCrosshairXValue(int index);

        virtual void calculateIfHasData();
//
//        virtual bool hasData(int index) const;

        const std::vector<std::pair<YTXTime, YTXTime> > getRestTime (){
            return restTime;
        }

        void setRestTime(std::vector<std::pair<YTXTime, YTXTime> > time)
        {
            restTime = time;
        }

        virtual void requestData(const std::string tag, const DataOption & dataOption, const std::string acceptableContent);

        virtual void firstFailRequestHandler(std::string tag);

        virtual void callback(std::string tag, std::string data);
        
        virtual void onFail(std::string tag);

        bool isInBidding();
        bool isNewTradeDay();
        bool isNewTradeDay(YTXTime time);
        
        bool isLessThanTradeDay(YTXTime tradedate);
        //接受过数据,但是data size 是0,info的tradedate有日期
        bool hasTradedate();

        virtual void getPrevAVGData(int count = 4);

        YTXTime fixPTime(YTXTime time);
        
        YTXTime fixPTimeToByAdding(YTXTime timefrom, YTXTime timeto);

        bool isNewMinK(YTXTime time1, YTXTime time2, int count);

//        void changeShowCount(int showCount);
//        void changeShowCount();

//        void turn(int step);
//        void turnLeft(int step);
//        void turnRight(int step);
//
//        void zoom(int step);
//        void zoomIn(int step);
//        void zoomOut(int step);

        

        virtual UpDropStatus::UpDropStatus getUpDropStatus(int index);

        void requestAvg(std::string tag = "calculate");

        void responseAvg(YTXJson::Value datas, YTXJson::Value info);
        
        void requestLSPData(long time);
        void responseAvgLSP(YTXJson::Value datas, YTXJson::Value info);

        void updateQuotedPrice(std::string id , std::string pricetime, double open, double close, double high, double low, double volume, double value, double hold, double avg);

        int getAddDay();

        void setAddDay(int addDay);

        std::string getUpdateTime();

        void setUpdateTime(std::string updateTime);

        int getBaseDrawCount();

        void setBaseDrawCount(int baseDrawCount);

        YTXTime getOpenTime();

        void setOpenTime(YTXTime openTime);

        YTXTime getCloseTime();

        void setCloseTime(YTXTime closeTime);

        TimeString getCalTimeString();

        std::vector<std::string> & getCalTimeString(SizeType::SizeType sizeType);

        void setCalTimeString(TimeString & calTimeString);

        int getDataCountBetweenTime(YTXTime time1,YTXTime time2);

        int getDataCountAfterTime(YTXTime time1);

        KLineItem getOCHL(int startIndex, int endIndex, double preClose);

        KLineItem getOCHL(int startIndex, double preClose);

        KLineItem getOCHL(double preClose);

        KLineItem getOCHL(YTXTime limitTime, double preClose);

        KLineItem getOCHLBySnapShort(YTXTime limitTime, double preClose);

        KLineItem getOCHL(YTXTime limitTime1, YTXTime limitTime2, double preClose);

        AVGData * prevAVGData;
        std::vector<std::string> prevAVGDates;

        YTXTime getTradedate();

        bool todayIsFinish();

        const std::vector<std::vector<double> > getLineDataWhateverEmpty(double prevValue);

        const std::vector<std::string> getDateDataWhateverEmpty();

        const std::vector<KLineItem> getKLineDataWhateverEmpty(double prevValue);

        virtual bool addWarningLineData(double value);

        virtual bool removeWarningLineData(double value);

        virtual bool updateWarningLineData(std::vector<double> value);

        virtual const std::vector<double> getWarningLineData(){
            return warningLineData;
        };

        virtual const std::pair<double, double> getWarningLineDataCloseNowValue() const;
        
        virtual const std::vector<EconomicCalendarData> getEconomicCalendarDataList() const;

        virtual void setEconomicCalendarDataWithoutValid(std::vector<EconomicCalendarData> economicCalendarDataList);
        
        virtual void addEconomicCalendarData(EconomicCalendarData economicCalendarData);

        virtual void addEconomicCalendarDataList(std::vector<EconomicCalendarData> economicCalendarDataList);

        virtual void removeEconomicCalendarData(EconomicCalendarData economicCalendarData);

        virtual void clearEconomicCalendarData();
        
        virtual void requestEconomicCalendarDataList();
        
        virtual void responseEconomicCalendarDataList(YTXJson::Value data);

        /*-1表示没有*/
        virtual const int getIndexByTimeDuration(YTXTimeDuration time);
        
        /*not_a_date_time表示没有*/
        virtual YTXTimeDuration getTimeDurationByIndex(size_t dataIndex);

        bool inTradeTime(YTXTimeDuration time);
        
        bool inTradeDate(YTXTime time);
        
        virtual UGCPoint getUserGraphWithPoint(float x1, float y1, Rectangle rect);
        
        void setBuyPoint(double buyPoint);
        
        void clearBuyPoints();
        
        std::list<double> getBuyPoints() const;

        void setLimitPositionInfos(const std::list<LimitPositionInfo> &limitPositionInfos);
        
        void addLimitPositionInfo(const LimitPositionInfo &limitPositionInfo);
        
        void clearLimitPositionInfos();
        
        const std::list<LimitPositionInfo> & getLimitPositionInfos() const;
    };
}


#endif /* defined(__Chart__AVGData__) */
